package com.server.db.jedis;

import java.util.ArrayList;
import com.sandking.config.SK_Config;
import java.util.Map;
import com.sandking.tools.SK_Plus;
import java.util.List;
import com.sandking.tools.SK_String;
import java.util.Collections;
import com.server.db.bean.Wj;
import com.sandking.tools.SK_List;
import java.util.Comparator;
import com.server.db.DbLock;
import com.sandking.constant.SK_ErrorCode;
import com.sandking.tools.SK_PageCount;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Set;
import com.sandking.tools.SK_Exception;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Jedis;
/**
 * 玩家
 * 1.做为Jedis单独使用的情况，我是不建议的!他不能保证线程安全性问题，没有数据补救的操作
 * 2.jedis的查询数据是没有顺序的
 */
public class WjJedis{
	static class WjSore implements Comparator<Wj> {
		@Override
		public int compare(Wj wj1, Wj wj2) {
			if (wj1.getId() > wj2.getId())
				return 1;
			else if (wj1.getId() < wj2.getId())
				return -1;
			else {
				return 0;
			}
		}
	}
	//表锁(重入锁)
	static final ReentrantLock tableLock = new ReentrantLock();
	
	static Comparator<Wj> comparator = new WjSore();
	
	/**
	 * 根据( id ) 查询
	 */
	public static Wj getById(int id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Wj wj = null;
		try{
			String key = "Wj_Object";
			String field = SK_Plus.b("id:",id).e();
			String json = jedis.hget(key,field);
			if(!SK_String.isEmpty(json))
				wj = Wj.createForJson(json);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wj;
	}
	
	public static List<Wj> getByIdIn(int[] ids){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Object";
			String[] strIds = new String[ids.length];
			for (int i = 0; i < strIds.length; i++) {
				strIds[i] = String.valueOf(ids[i]);
			}
			List<String> jsons = jedis.hmget(key,strIds);
			 wjs = Wj.createForJson(jsons);
		}catch (Exception e) {
			
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wjs;
	}
	/**
	 * 根据( 昵称 ) 查询
	 */
	public static Wj getByNc(String nc){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Wj wj = null;
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b("nc:",nc).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				wj = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wj;
	}
	
	/**
	 * 根据( 账号 ) 查询
	 */
	public static Wj getByZh(String zh){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Wj wj = null;
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b("zh:",zh).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				wj = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wj;
	}
	
	/**
	 * 根据( 账号  密码 ) 查询
	 */
	public static Wj getByZhMm(String zh, String mm){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Wj wj = null;
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b("zh,mm:",zh,"_",mm).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				wj = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wj;
	}
	
	/**
	 * 根据( 用户类型_id ) 查询
	 */
	public static List<Wj> getByYhlx_id(int yhlx_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b(key,"yhlx_id:",yhlx_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Wj_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				wjs = Wj.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getByPageYhlx_id(int yhlx_id,int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getByYhlx_id(yhlx_id);
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	
	/**
	 * 根据( 服务器_id ) 查询
	 */
	public static List<Wj> getByFwq_id(int fwq_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b(key,"fwq_id:",fwq_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Wj_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				wjs = Wj.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getByPageFwq_id(int fwq_id,int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getByFwq_id(fwq_id);
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	
	/**
	 * 根据( 渠道 ) 查询
	 */
	public static List<Wj> getByQd(String qd){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b(key,"qd:",qd).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Wj_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				wjs = Wj.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getByPageQd(String qd,int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getByQd(qd);
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	
	/**
	 * 根据( 联盟_id ) 查询
	 */
	public static List<Wj> getByLm_id(int lm_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b(key,"lm_id:",lm_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Wj_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				wjs = Wj.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getByPageLm_id(int lm_id,int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getByLm_id(lm_id);
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	
	/**
	 * 根据( 渠道  用户类型_id ) 查询
	 */
	public static List<Wj> getByQdYhlx_id(String qd, int yhlx_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Index";
			String field = SK_Plus.b(key,"qd,yhlx_id:",qd,"_",yhlx_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Wj_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				wjs = Wj.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getByPageQdYhlx_id(String qd, int yhlx_id,int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getByQdYhlx_id(qd,yhlx_id);
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	

	public static List<Wj> getAll(){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs = new ArrayList<Wj>();
		try{
			String key = "Wj_Object";
			List<String> jsons = jedis.hvals(key);
			wjs = Wj.createForJson(jsons);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(wjs, comparator);
		return wjs;
	}
	
	
	public static List<Wj> getAllByPage(int page,int size,SK_PageCount pageCount){
		List<Wj> wjs = getAll();
		wjs = SK_List.getPage(wjs, page, size, pageCount);
		return wjs;
	}
	
	
	public static Wj putData(Wj wj,Pipeline p,int type) throws SK_Exception{
		boolean isLock = (type == SK_Config.CHECK_ALL_INDEX);
		Map<String,String> updateIndexs = null;
		if(type == SK_Config.CHECK_UPDATE_INDEX){
			updateIndexs = wj.getUpdateIndexs();
			isLock = updateIndexs.containsKey("isUpdtaeUnique");
		}
		try{
			DbLock.lock(wj.getId(),DbLock.wj_locks);
			if(isLock)tableLock.lock();
			switch (type) {
			case SK_Config.CHECK_ALL_INDEX:
				checkUniqueIndex(wj);
				break;
			case SK_Config.CHECK_UPDATE_INDEX:
				checkUniqueIndex(updateIndexs);
				break;
			}
			if(type == SK_Config.CHECK_UPDATE_INDEX){
				removeData(wj);
			}
			// ---------------------- 主键索引 ----------------------
			String key = "Wj_Object";
			String field = SK_Plus.b("id:",wj.getId()).e();
			String data = wj.toJson();
			p.hset(key,field,data);
			
			// ---------------------- 唯一索引 ----------------------
			String primaryKey = String.valueOf(wj.getId());
			key = "Wj_Index";
			
			field = SK_Plus.b("nc:",wj.getNc()).e();
			p.hset(key,field,primaryKey);
			
			field = SK_Plus.b("zh:",wj.getZh()).e();
			p.hset(key,field,primaryKey);
			
			field = SK_Plus.b("zh,mm:",wj.getZh(),"_",wj.getMm()).e();
			p.hset(key,field,primaryKey);
			
			// ---------------------- 聚集索引 ----------------------
			field = SK_Plus.b(key,"yhlx_id:",wj.getYhlx_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"fwq_id:",wj.getFwq_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"qd:",wj.getQd()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"lm_id:",wj.getLm_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"qd,yhlx_id:",wj.getQd(),"_",wj.getYhlx_id()).e();
			p.sadd(field, primaryKey);
			
		}finally{
			 DbLock.unlock(wj.getId(),DbLock.wj_locks);
			 if(isLock)tableLock.unlock();
		}
		return wj;
	}
	
	public static List<Wj> putDataAll(List<Wj> wjs,int type){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Wj> wjs_ = new ArrayList<Wj>();
		try{
			Pipeline p = jedis.pipelined();
			for(Wj wj : wjs){
				try {
					wjs_.add(putData(wj,p,type));
				} catch (SK_Exception e) {
					e.printStackTrace();
				}
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return wjs_;
	}
	
	public static void removeData(Wj wj){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			removeData(wj,p);
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	/**
	 * 清空一个缓存
	 */
	public static void removeData(Wj wj,Pipeline p){
		try{
			DbLock.lock(wj.getId(),DbLock.wj_locks);
			// ---------------------- 主键索引 ----------------------
			String key = "Wj_Object";
			String field = SK_Plus.b("id:",wj.getId_Unique()).e();
			p.hdel(key,field);
			
			// ---------------------- 唯一索引 ----------------------
			key = "Wj_Index";
			
			field = SK_Plus.b("nc:",wj.getNc_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			field = SK_Plus.b("zh:",wj.getZh_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			field = SK_Plus.b("zh,mm:",wj.getZhMm_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			// ---------------------- 聚集索引 ----------------------
			String primaryKey = String.valueOf(wj.getId());
			field = SK_Plus.b(key,"yhlx_id:",wj.getYhlx_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"fwq_id:",wj.getFwq_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"qd:",wj.getQd_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"lm_id:",wj.getLm_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"qd,yhlx_id:",wj.getQdYhlx_id_Index()).e();
			p.srem(field, primaryKey);
			
		}finally{
			 DbLock.unlock(wj.getId(),DbLock.wj_locks);
		}
	}

	public static void removeDataAll(List<Wj> wjs){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			for(Wj wj : wjs){
				removeData(wj,p);
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	public static Wj insert(Wj wj){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			if(wj.getId() < 1){
				try {
					tableLock.lock();
					wj.setId(jedis.hincrBy("primaryKey", Wj.CLASS_NAME,1).intValue());
				}finally{
					tableLock.unlock();
				}
			}
			DbLock.lock(wj.getId(),DbLock.wj_locks);
			try {
				wj = putData(wj, p, SK_Config.CHECK_ALL_INDEX);
				p.sync();
				return wj;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(wj.getId(),DbLock.wj_locks);
		}
		return null;
    }
    
    public static List<Wj> insertBatch(List<Wj> wjs){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
    	try{
			wjs = putDataAll(wjs, SK_Config.CHECK_ALL_INDEX);
			jedis.hincrBy("primaryKey", Wj.CLASS_NAME,wjs.size());
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
    	return wjs;
    }
    
    public static Wj update(Wj wj){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			DbLock.lock(wj.getId(),DbLock.wj_locks);
			try{
				wj = putData(wj,p,SK_Config.CHECK_UPDATE_INDEX);
				p.sync();
				return wj;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(wj.getId(),DbLock.wj_locks);
		}
		return null;
    }
    
    public static List<Wj> updateBatch(List<Wj> wjs){
    	removeDataAll(wjs);
		putDataAll(wjs,SK_Config.CHECK_UPDATE_INDEX);
    	return wjs;
    }
    
    public static boolean delete(Wj wj){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		boolean bool = true;
		try{
			DbLock.lock(wj.getId(),DbLock.wj_locks);
	    	removeData(wj,p);
	    	p.sync();
	    }finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(wj.getId(),DbLock.wj_locks);
		}
	    return bool;
    }
    
    public static boolean deleteBatch(List<Wj> wjs){
    	boolean bool = true;
    	removeDataAll(wjs);
    	return bool;
    }
    
    
    
    //检查唯一索引
	private static void checkUniqueIndex(Wj wj) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "Wj_Object";
			String field = SK_Plus.b("id:",SK_Plus.b(wj.getId()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Id_IndexName,"=",field).e());
				
			key = "Wj_Index";
			field = SK_Plus.b("nc:",SK_Plus.b(wj.getNc()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Nc_IndexName,"=",field).e());
				
			key = "Wj_Index";
			field = SK_Plus.b("zh:",SK_Plus.b(wj.getZh()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Zh_IndexName,"=",field).e());
				
			key = "Wj_Index";
			field = SK_Plus.b("zh,mm:",SK_Plus.b(wj.getZh(),"_",wj.getMm()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.ZhMm_IndexName,"=",field).e());
				
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
	
	/** 检查(改变的)唯一索引 */
	private static void checkUniqueIndex(Map<String,String> indexs) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "";
			for (Map.Entry<String, String> index : indexs.entrySet()) {
				switch (index.getKey()) {
				case Wj.Id_IndexName:
					key = "Wj_Object";
					if(jedis.hexists(key,SK_Plus.b("id:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Id_IndexName,"=",index.getValue()).e());
					break;
				case Wj.Nc_IndexName:
					key = "Wj_Index";
					if(jedis.hexists(key,SK_Plus.b("nc:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Nc_IndexName,"=",index.getValue()).e());
					break;
				case Wj.Zh_IndexName:
					key = "Wj_Index";
					if(jedis.hexists(key,SK_Plus.b("zh:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.Zh_IndexName,"=",index.getValue()).e());
					break;
				case Wj.ZhMm_IndexName:
					key = "Wj_Index";
					if(jedis.hexists(key,SK_Plus.b("zh,mm:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Wj.ZhMm_IndexName,"=",index.getValue()).e());
					break;
				}
			}
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
}